package cn.yangliu.task.entity;

import cn.yangliu.task.enums.TaskExecuteStatusEnum;
import cn.yangliu.task.enums.TaskStatusEnum;
import cn.yangliu.task.service.TaskService;
import cn.yangliu.task.utils.AppUtils;
import cn.yangliu.task.utils.TaskUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

public class Task implements Serializable, Runnable {

    private TaskService taskService;

    private Object target;

    private Class<?> targetClass;

    public Task() {
        taskService = AppUtils.getBean(TaskService.class);
    }

    private int pageSize;

    private int currentPage;

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    private static final long serialVersionUID = -8982269914079486764L;
    private String id; //主建

    private String clazz; //任务类

    private String cron;//表达式

    private Integer status; //任务状态

    private Integer excuteStatus; //任务执行状态

    private String method;//任务要调度的方法

    private String name;//任务名称

    private Integer excuteCount; //任务已执行次数

    private Integer excuteTotalCount; //任务计划执行次数

    private LocalDateTime updateTime;//任务更新时间

    private LocalDateTime createTime;//任务创建时间

    private String remark;//备注

    private String config; //用户自定义配置

    private LocalDateTime queryStartDate;

    private LocalDateTime queryEndDate;

    private String condition;

    private String statusDesp;

    private String excuteStatusDesp;

    public String getConfig() {
        return config;
    }

    public void setConfig(String config) {
        this.config = config;
    }

    public String getStatusDesp() {
        if (status != null) {
            return TaskStatusEnum.getDespByStatus(status);
        }
        return null;
    }

    public String getExcuteStatusDesp() {
        if (excuteStatus != null) {
            return TaskExecuteStatusEnum.getDespByStatus(excuteStatus);
        }
        return null;
    }

    public Integer getExcuteCount() {
        return excuteCount;
    }

    public void setExcuteCount(Integer excuteCount) {
        this.excuteCount = excuteCount;
    }

    public Integer getExcuteTotalCount() {
        return excuteTotalCount;
    }

    public void setExcuteTotalCount(Integer excuteTotalCount) {
        this.excuteTotalCount = excuteTotalCount;
    }

    public String getCondition() {
        return condition;
    }

    public void setCondition(String condition) {
        this.condition = condition;
    }

    public LocalDateTime getQueryStartDate() {
        return queryStartDate;
    }

    public void setQueryStartDate(LocalDateTime queryStartDate) {
        this.queryStartDate = queryStartDate;
    }

    public LocalDateTime getQueryEndDate() {
        return queryEndDate;
    }

    public void setQueryEndDate(LocalDateTime queryEndDate) {
        this.queryEndDate = queryEndDate;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
        try {
            targetClass = Class.forName(clazz);
            target = AppUtils.getBean(targetClass);
        } catch (Exception e) {
         // throw new NullPointerException("class"+clazz+"不存在");
        }
    }

    public String getCron() {
        return cron;
    }

    public void setCron(String cron) {
        this.cron = cron;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Integer getExcuteStatus() {
        return excuteStatus;
    }

    public void setExcuteStatus(Integer excuteStatus) {
        this.excuteStatus = excuteStatus;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDateTime getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    private static final Logger logger = LoggerFactory.getLogger(Task.class);

    @Override
    public void run() {
        try {
            if (!TaskUtils.checkExcuteCount(this)) {
                return;
            }

            Method method = null;
            boolean hasConfig = false;
            try{
                method = targetClass.getDeclaredMethod(getMethod());//默认找无参方法
            }catch (Exception e){
                method = targetClass.getDeclaredMethod(getMethod(),String.class);//没有找到无参方法再找有参方法
                hasConfig = true;
            }

            logger.info("执行任务" + getId());
            if (hasConfig){
                method.invoke(target,config);
            }else {
                method.invoke(target);
            }

            setExcuteStatus(TaskExecuteStatusEnum.SUCCESS.getStatus());
            logger.info("任务执行成功" + getId());
            //更新执行次数
            taskService.updateExcuteCount(this);
        } catch (Exception e) {
            logger.info("任务执行失败" + getId());
            setExcuteStatus(TaskExecuteStatusEnum.FAIL.getStatus());
            taskService.updateTaskDBInfo(this);
            throw new RuntimeException(e.getMessage(), e);
        }

        //更新任务执行状态
        logger.info("更新任务执行状态" + getId());
        taskService.updateTaskDBInfo(this);

    }
}
